package com.example.crowdfunding.service.impl;

import com.example.crowdfunding.constant.CrowdConstant;
import com.example.crowdfunding.entity.Admin;
import com.example.crowdfunding.entity.AdminExample;
import com.example.crowdfunding.mapper.AdminMapper;
import com.example.crowdfunding.service.api.AdminService;
import com.example.crowdfunding.utils.CrowdUtils;
import com.example.crowdfunding.utils.exception.LoginFailedException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * The type Admin service.
 */
@Service
public class AdminServiceImpl implements AdminService {

    /**
     * The Logger.
     */
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    BCryptPasswordEncoder passwordEncoder;
    @Resource
    private AdminMapper adminMapper;

    @Override
    public void saveAdmin(Admin admin) {

        // 数据库中不存放明文密码
        String originalPwd = admin.getUserPwd();
        String encodePwd = passwordEncoder.encode(originalPwd);

        admin.setUserPwd(encodePwd);
        adminMapper.insert(admin);

        // 测试事务的异常回滚
        // throw new RuntimeException("测试事务的异常回滚");
    }

    @Override
    public Admin getAdminByAcctAndPwd(String loginAccount, String userPwd) {

        // 1.根据账户名去查数据库
        List<Admin> adminList = getAdminList(loginAccount);
        // 2.admin为空 --> 抛出登录账号不存在异常
        if (adminList.size() <= 0) {
            logger.warn("账户名[" + loginAccount + "]不存在");
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        if (adminList.size() > 1) {
            logger.error("查询到数据库中存在多条账户名为" + loginAccount + "的记录");
            throw new RuntimeException(CrowdConstant.MESSAGE_DATABASE_TOO_MANY_RESULT);
        }
        // 3.admin不为空 --> 取出数据库中的暗文密码
        Admin admin = adminList.get(0);
        String pwdFromDatabase = admin.getUserPwd();

        // 4.用数据库的暗文与加密后的密码进行比较
        String pwdFromPage = CrowdUtils.md5(userPwd);
        if (Objects.equals(pwdFromPage, pwdFromDatabase)) {
            // 登录成功
            return admin;
        } else {
            logger.warn("账户[" + loginAccount + "]输入了错误的密码[" + userPwd + "]");
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }

    }

    @Override
    public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {

        // 1.调用page helper开启分页功能
        PageHelper.startPage(pageNum, pageSize);

        // 2.执行查询
        List<Admin> adminList = adminMapper.selectAdminByKeyword(keyword);

        // 3.将以上的集合封装到PageInfo中
        PageInfo<Admin> pageInfo = new PageInfo<>(adminList);

        logger.debug("adminList分页信息：\n" + pageInfo);

        return pageInfo;
    }

    @Override
    public void removeAdmin(Integer adminId) {

        adminMapper.deleteByPrimaryKey(adminId);
    }

    @Override
    public Boolean getAdminByAcct(String acctName) {

        List<Admin> adminList = getAdminList(acctName);
        return adminList.size() > 0;
    }

    @Override
    public Admin getRealAdminByAcct(String acctName) {

        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        criteria.andLoginAcctEqualTo(acctName);
        return adminMapper.selectByExample(adminExample).get(0);
    }

    @Override
    public Admin getAdminById(Integer id) {

        return adminMapper.selectByPrimaryKey(id);
    }

    @Override
    public void updateAdminByCondition(Admin admin) {

        String originalPwd = admin.getUserPwd();
        String encodePwd = passwordEncoder.encode(originalPwd);
        admin.setUserPwd(encodePwd);
        adminMapper.updateByPrimaryKeySelective(admin);
    }

    @Override
    public void saveAdminRoleRelationship(Integer adminId, List<Integer> roleIds) {

        adminMapper.delOldRelationship(adminId);
        if (roleIds != null && roleIds.size() > 0) {
            adminMapper.insertNewRelationship(adminId, roleIds);
        }

    }

    private List<Admin> getAdminList(String acctName) {
        // 1.根据账号查询admin
        // 1.1创建AdminExample对象
        AdminExample adminExample = new AdminExample();

        // 1.2创建criteria对象
        AdminExample.Criteria criteria = adminExample.createCriteria();

        // 1.3在criteria对象中封装查询条件（sql语句）
        criteria.andLoginAcctEqualTo(acctName);

        //1.4用adminMapper执行sql查询
        return adminMapper.selectByExample(adminExample);
    }

}
